package controller

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/periodTask"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEnv"
	"gitee.com/fierce_wolf/go-fox-edge-common/httpserver"
	"go-fox-edge-kernel-manager/repository"
	"go-fox-edge-kernel-manager/utils/PageUtils"
	"strings"
)

type repoCloudCompController struct {
}

func (e *repoCloudCompController) init() {
	httpserver.Server.POST("/repository/page", e.selectPageList)
	httpserver.Server.POST("/repository/download", e.download)
	httpserver.Server.POST("/repository/scan", e.scanPackFile)
	httpserver.Server.POST("/repository/install", e.installPackFile)
	httpserver.Server.POST("/repository/delete", e.deleteEntity)
}

func (e *repoCloudCompController) selectPageList(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	// 提取业务参数
	source := Map.GetString(body, "source", "")
	modelType := Map.GetString(body, "modelType", "")
	pageNum := Map.GetInt(body, "pageNum", 1)
	pageSize := Map.GetInt(body, "pageSize", 10)

	// 简单校验参数
	if Method.HasEmpty(modelType) || Map.HasNull(body, "pageNum", "pageSize") {
		return nil, errors.New("参数不能为空: modelType, pageNum, pageSize")
	}

	// 查询本地/远程文件列表
	list := make([]map[string]interface{}, 0)
	if "local" == source {
		list = repository.CloudCache.ReadList(modelType)
		if len(list) == 0 {
			val, err := repository.CloudFileInstallService.QueryUriListFile(modelType)
			if err != nil {
				return nil, err
			}

			list = val
			repository.CloudCache.SaveList(modelType, list)
		}
	} else {
		val, err := repository.CloudFileInstallService.QueryUriListFile(modelType)
		if err != nil {
			return nil, err
		}

		list = val
		repository.CloudCache.SaveList(modelType, list)
	}

	// 如果是服务类型，那么进行一次规则过滤
	if modelType == "service" {
		val, err := repository.LocalAppConf.Filter(list)
		if err != nil {
			return nil, err
		}
		list = val
	}

	// 分析本地的安装状态
	for _, data := range list {
		repository.CloudFileInstallService.ExtendLocalStatus(data)
	}

	resultList := make([]map[string]interface{}, 0)
	for _, value := range list {
		result := true
		fieldName := ""

		// 模糊搜索
		fieldName = "keyword"

		if Map.Has(body, fieldName) {
			fuzzy := false
			fuzzy = fuzzy || strings.Contains(strings.ToLower(Map.GetString(value, "modelName", "")), strings.ToLower(Map.GetString(body, fieldName, "")))
			fuzzy = fuzzy || strings.Contains(strings.ToLower(Map.GetString(value, "modelType", "")), strings.ToLower(Map.GetString(body, fieldName, "")))
			fuzzy = fuzzy || strings.Contains(strings.ToLower(Map.GetString(value, "description", "")), strings.ToLower(Map.GetString(body, fieldName, "")))
			fuzzy = fuzzy || strings.Contains(strings.ToLower(Map.GetString(value, "manufacturer", "")), strings.ToLower(Map.GetString(body, fieldName, "")))
			fuzzy = fuzzy || strings.Contains(strings.ToLower(Map.GetString(value, "deviceType", "")), strings.ToLower(Map.GetString(body, fieldName, "")))

			result = result && fuzzy
		}
		if !result {
			continue
		}

		// 后面是精确匹配
		fieldName = "version"
		if Map.Has(body, fieldName) {
			result = result && strings.Contains(Map.GetString(value, fieldName, ""), Map.GetString(body, fieldName, ""))
		}
		fieldName = "version"
		if Map.Has(body, fieldName) {
			result = result && strings.Contains(Map.GetString(value, fieldName, ""), Map.GetString(body, fieldName, ""))
		}
		fieldName = "status"
		if Map.Has(body, fieldName) {
			lastVersion := Map.GetMap(value, "lastVersion", make(map[string]interface{}))
			result = result && Map.GetInt(lastVersion, fieldName, 0) == Map.GetInt(body, fieldName, 0)
		}

		if result {
			resultList = append(resultList, value)
		}
	}

	// 分页查询
	return PageUtils.GetMapPageList(resultList, pageNum, pageSize), nil
}

func (e *repoCloudCompController) scanPackFile(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	if edgeEnv.IsDockerEnv() {
		return nil, errors.New("运行环境为docker，该环境不支持该操作")
	}

	// 提取业务参数
	modelType := Map.GetString(body, "modelType", "")

	// 简单校验参数
	if Method.HasEmpty(modelType) {
		return nil, errors.New("参数不能为空: modelType")
	}

	periodTask.InsertTask(&repository.RepoScanStatusTask{ModelType: modelType})
	return nil, nil
}

func (e *repoCloudCompController) installPackFile(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	if edgeEnv.IsDockerEnv() {
		return nil, errors.New("运行环境为docker，该环境不支持该操作")
	}

	// 提取业务参数
	modelType := Map.GetString(body, "modelType", "")
	modelName := Map.GetString(body, "modelName", "")
	version := Map.GetString(body, "version", "")
	stage := Map.GetString(body, "stage", "")
	component := Map.GetString(body, "component", "")

	// 简单校验参数
	if Method.HasEmpty(modelType, modelName, version, stage, component) {
		return nil, errors.New("参数不能为空: modelType, modelName, version, stage, component")
	}

	// 创建所属的组件实体
	err := repository.CloudFileInstallService.InsertRepoCompEntity(modelType, modelName)
	if err != nil {
		return nil, err
	}

	// 安装文件组件
	repository.CloudFileInstallService.InstallFile(modelType, modelName, version, stage, component)

	return nil, nil
}

func (e *repoCloudCompController) download(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	if edgeEnv.IsDockerEnv() {
		return nil, errors.New("运行环境为docker，该环境不支持该操作")
	}

	list := Map.GetSlice(body, "list", nil)

	// 提取业务参数
	if Method.HasEmpty(list) {
		return nil, errors.New("参数不能为空: list")
	}

	for _, v := range list {
		data := v.(map[string]interface{})

		modelType := Map.GetString(data, "modelType", "")
		modelName := Map.GetString(data, "modelName", "")
		version := Map.GetString(data, "version", "")
		stage := Map.GetString(data, "stage", "")
		pathName := Map.GetString(data, "pathName", "")
		component := Map.GetString(data, "component", "")

		if Method.HasEmpty(modelType, modelName, version, stage, pathName, component) {
			return nil, errors.New("参数不能为空: modelType, modelName, version, stage, pathName, component")
		}

		err := repository.CloudFileInstallService.TestUrlFileCanBeOpen(modelType, modelName, version, pathName)
		if err != nil {
			return nil, errors.New("Fox-Cloud上文件无法下载，请联系该模块的发布者!")
		}

		task := &repository.RepoDownLoadTask{
			ModelType: modelType,
			ModelName: modelName,
			Version:   version,
			Stage:     stage,
			PathName:  pathName,
			Component: component,
		}

		periodTask.InsertTask(task)
	}

	return nil, nil
}

func (e *repoCloudCompController) deleteEntity(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	if edgeEnv.IsDockerEnv() {
		return nil, errors.New("运行环境为docker，该环境不支持该操作")
	}

	list := Map.GetSlice(body, "list", nil)

	// 提取业务参数
	if Method.HasEmpty(list) {
		return nil, errors.New("参数不能为空: list")
	}

	for _, v := range list {
		data := v.(map[string]interface{})

		modelType := Map.GetString(data, "modelType", "")
		modelName := Map.GetString(data, "modelName", "")
		version := Map.GetString(data, "version", "")
		stage := Map.GetString(data, "stage", "")
		component := Map.GetString(data, "component", "")

		if Method.HasEmpty(modelType, modelName, version, stage, component) {
			return nil, errors.New("参数不能为空: modelType, modelName, version, stage, component")
		}

		repository.CloudFileInstallService.DeletePackageFile(modelType, modelName, version, stage, component)
	}

	return nil, nil
}
